package ar.com.profertil.utils.certificado;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.Date;
import java.util.Enumeration;

import javax.naming.InitialContext;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.sap.engine.interfaces.keystore.KeystoreManager;
import com.sun.net.ssl.KeyManagerFactory;

/**
 * The Class Certificado.
 */
public class Certificado {

    /**
     * Instantiates a new certificado.
     *
     * @param psFileName the ps file name
     * @param psPassword the ps password
     * @param keyStorageView the key storage view
     * @param sAlias the alias of a key in the key storage view
     * @param useKeyStoreManager the use key store manager
     * @throws Exception the exception
     */
    public Certificado(String psFileName, 
			   		   String psPassword,
			   		   String keyStorageView,
			   		   String sAlias,
    				   boolean useKeyStoreManager) throws Exception {
        clavePura = null;
        sFileName = psFileName;
        sPassword = psPassword;
        if(useKeyStoreManager) {
        	LoadInfoSAP(keyStorageView, sAlias);
        } else {
        	LoadInfo();
        }
    }

    /**
     * Load info sap.
     *
     * @param keyStorageView the key storage view
     * @throws Exception the exception
     */
    private void LoadInfoSAP(String keyStorageView) throws Exception {
		InitialContext ctx = new InitialContext();
		Object o = ctx.lookup("keystore");
		KeystoreManager manager = (KeystoreManager)o;
		KeyStore keyStore = manager.getKeystore(keyStorageView);
        Enumeration<String> enumAliases = keyStore.aliases();
        for(java.security.Key k = null; enumAliases.hasMoreElements() && k == null;) {
            String sAlias = (String)enumAliases.nextElement();
            X509Certificate X509Cert = (X509Certificate)keyStore.getCertificate(sAlias);
            k = keyStore.getKey(sAlias, sPassword.toCharArray());
            if(k != null) {
                clavePura = (RSAPrivateCrtKey)k;
                clavePrivada = new ClavePrivada(k);
                clavePublica = new Clave(k);
                usuario = new Usuario(X509Cert.getSubjectDN().toString());
                dSinceDate = X509Cert.getNotBefore();
                dToDate = X509Cert.getNotAfter();
            }
        }

    }
    
    /**
     * Load info sap.
     *
     * @param keyStorageView the key storage view
     * @param sAlias the alias of a key in the key storage view
     * @throws Exception the exception
     */
    private void LoadInfoSAP(String keyStorageView, String sAlias) throws Exception {
		InitialContext ctx = new InitialContext();
		Object o = ctx.lookup("keystore");
		KeystoreManager manager = (KeystoreManager)o;
		KeyStore keyStore = manager.getKeystore(keyStorageView);
		X509Certificate X509Cert = (X509Certificate)keyStore.getCertificate(sAlias);
		java.security.Key k = keyStore.getKey(sAlias, sPassword.toCharArray());
        if(k != null) {
            clavePura = (RSAPrivateCrtKey)k;
            clavePrivada = new ClavePrivada(k);
            clavePublica = new Clave(k);
            usuario = new Usuario(X509Cert.getSubjectDN().toString());
            dSinceDate = X509Cert.getNotBefore();
            dToDate = X509Cert.getNotAfter();
        }
        

    }
    
    /**
     * Load info.
     *
     * @throws Exception the exception
     */
    private void LoadInfo() throws Exception {
        try {
            Security.setProperty("putProviderProperty", "SunX509");
            Security.addProvider(new BouncyCastleProvider());
            FileInputStream fisCertFile = new FileInputStream(sFileName);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509", "SunJSSE");
            KeyStore ks = KeyStore.getInstance("PKCS12");
            char[] sPass = null;
            if(sPassword != null) {
            	sPass = sPassword.toCharArray();
            }
            ks.load(fisCertFile, sPass);
            kmf.init(ks, sPass);
            Enumeration<String> enumAliases = ks.aliases();
            for(java.security.Key k = null; enumAliases.hasMoreElements() && k == null;) {
                String sAlias = (String)enumAliases.nextElement();
                X509Certificate X509Cert = (X509Certificate)ks.getCertificate(sAlias);
                k = ks.getKey(sAlias, sPass);
                if(k != null) {
                    clavePura = (RSAPrivateCrtKey)k;
                    clavePrivada = new ClavePrivada(k);
                    clavePublica = new Clave(k);
                    usuario = new Usuario(X509Cert.getSubjectDN().toString());
                    dSinceDate = X509Cert.getNotBefore();
                    dToDate = X509Cert.getNotAfter();
                }
            }

            fisCertFile.close();
        } catch(Exception exception) {
            sError = "[" + getClass().getName() + "]";
            sError += "Error en la apertura del certificado [";
            sError += sFileName + "]\n";
            sError += exception.toString();
            throw new Exception(sError);
        }
    }

    /**
     * Gets the cA name.
     *
     * @return the cA name
     */
    public String getCAName() {
        return sCAName;
    }

    /**
     * Gets the cA country.
     *
     * @return the cA country
     */
    public String getCACountry() {
        return sCACountry;
    }

    /**
     * Gets the since date.
     *
     * @return the since date
     */
    public Date getSinceDate() {
        return dSinceDate;
    }

    /**
     * Gets the to date.
     *
     * @return the to date
     */
    public Date getToDate() {
        return dToDate;
    }

    /**
     * Gets the clave privada.
     *
     * @return the clave privada
     */
    public ClavePrivada getClavePrivada() {
        return clavePrivada;
    }

    /**
     * Gets the clave publica.
     *
     * @return the clave publica
     */
    public Clave getClavePublica() {
        return clavePublica;
    }

    /**
     * Gets the usuario.
     *
     * @return the usuario
     */
    public Usuario getUsuario() {
        return usuario;
    }

    /**
     * Gets the clave pura.
     *
     * @return the clave pura
     */
    public PrivateKey getClavePura() {
        return clavePura;
    }

    /** The clave privada. */
    private ClavePrivada clavePrivada;
    
    /** The clave publica. */
    private Clave clavePublica;
    
    /** The usuario. */
    private Usuario usuario;
    
    /** The s file name. */
    private String sFileName;
    
    /** The s error. */
    private String sError;
    
    /** The s password. */
    private String sPassword;
    
    /** The s ca name. */
    private String sCAName;
    
    /** The s ca country. */
    private String sCACountry;
    
    /** The d since date. */
    private Date dSinceDate;
    
    /** The d to date. */
    private Date dToDate;
    
    /** The clave pura. */
    private PrivateKey clavePura;
}
